package com.jmb.apiplatform.service.impl;

import com.jmb.apiplatform.exception.ValidException;
import com.jmb.apiplatform.mapper.ApiTestAssertMapper;
import com.jmb.apiplatform.mapper.ApiTestCaseMapper;
import com.jmb.apiplatform.pojo.ApiTestAssert;
import com.jmb.apiplatform.service.ApiTestAssertService;
import com.jmb.apiplatform.util.ValidUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

/**
* @author jinbo
* @description 针对表【api_test_assert】的数据库操作Service实现
* @createDate 2025-02-06 15:52:05
*/

@Slf4j
@Service
public class ApiTestAssertServiceImpl implements ApiTestAssertService{
    @Autowired
    private ApiTestAssertMapper apiTestAssertMapper;
    @Autowired
    private ApiTestCaseMapper apiTestCaseMapper;

    @Override
    public void saveApiTestAssert(ApiTestAssert apiTestAssert) throws ValidException {
        // 检验数据
        this.checkDO(apiTestAssert);
        Integer caseId = apiTestAssert.getCaseId();
        // 判断caseId是否存在相同的order
        ApiTestAssert testAssert = new ApiTestAssert();
        testAssert.setOrderId(apiTestAssert.getOrderId());
        testAssert.setCaseId(apiTestAssert.getCaseId());
        // 判断caseId是否存在
        if (apiTestCaseMapper.selectCaseInfoByCaseId(caseId)==null){
            log.warn("新增断言时，数据缓存用例编号不存在,caseId={}",caseId);
            throw  new ValidException("数据缓存用例编号不存在");
        }
        Date date = new Date();
        apiTestAssert.setCreatedTime(date);
        apiTestAssert.setUpdateTime(date);
        if (apiTestAssert.getType() == 3) { //提取数据类型   0json/1html/2header/3responseCode
            apiTestAssert.setExpression(null);
        }
        apiTestAssertMapper.insertAssert(apiTestAssert);

    }

    @Override
    public void editApiTestAssert(ApiTestAssert apiTestAssert) throws ValidException {
        // 校验数据
        this.checkDO(apiTestAssert);
        // 判断caseId是否存在
        Integer caseId = apiTestAssert.getCaseId();
        if (apiTestCaseMapper.selectCaseInfoByCaseId(caseId)==null){
            log.warn("修改断言时，数据缓存用例编号不存在,caseId={}",caseId);
            throw  new ValidException("数据缓存用例编号不存在");
        }
        if (apiTestAssert.getType()==3){ // 提取数据类型   0json/1html/2header/3responseCode
            apiTestAssert.setExpression(null);
        }
        apiTestAssert.setUpdateTime(new Date());
        apiTestAssertMapper.updateAssert(apiTestAssert);
    }

    /**
     * 根据编号删除断言
     * @param assertId 断言编号
     */
    @Override
    public void removeAssertById(Integer assertId) {
        if (assertId==null){
            log.warn("删除断言时，断言编号不能为空");
        }
        apiTestAssertMapper.deleteAssertById(assertId);


    }

    /**
     * 删除测试用例所有的断言
     * @param caseId 测试用例编号
     */
    @Override
    public void removeAssertByCaseId(Integer caseId) {
        if (caseId==null){
            log.warn("删除断言时，用例编号不能为空");
        }
        apiTestAssertMapper.deleteAssertByCaseId(caseId);
    }

    public void checkDO(ApiTestAssert apiTestAssert) throws ValidException {
        Integer caseId = apiTestAssert.getCaseId();
        ValidUtil.notNUll(caseId, "用例编号不能为空");

        String assertName = apiTestAssert.getAssertName();
        ValidUtil.notNUll(assertName, "断言名称不能为空");
        ValidUtil.notEmpty(assertName, "断言名称不能为空");
        ValidUtil.length(assertName, 1,100, "断言名称长度必须小于100");

        Integer type = apiTestAssert.getType();
        ValidUtil.notNUll(type, "提取数据类型不能为空");
        ValidUtil.size(type, 0, 4,"提取数据类型必须为0~4");

        String expression = apiTestAssert.getExpression();
        if (type < 3) { // 提取数据类型   0json/1html/2header/3responseCode/4runtime
            ValidUtil.notNUll(expression, "提取表达式不能为空");
            ValidUtil.notEmpty(expression, "提取表达式不能为空");
            ValidUtil.length(expression, 1,50, "提取表达式长度必须小于50");
        }

        Integer operator = apiTestAssert.getOperator();
        ValidUtil.notNUll(operator, "操作符不能为空");
        ValidUtil.size(operator, 0, 12,"操作符必须为0~12");

        String exceptedResult = apiTestAssert.getExceptedResult();
        if (operator != 8 && operator != 9 && operator != 11 && operator != 12) {
            ValidUtil.notNUll(exceptedResult, "预期结果不能为空");
            ValidUtil.notEmpty(exceptedResult, "预期结果不能为空");
        }
        ValidUtil.length(exceptedResult, 0, 1000,"预期结果长度必须小于1000");

        Integer order = apiTestAssert.getOrderId();
        ValidUtil.notNUll(order, "排序不能为空");

        // 检查 0json/1html/2header/3responsecode
        if (type == 0) {
            ValidUtil.isJsonPath(expression);
        } else if (type == 1) {
            ValidUtil.isXmlPath(expression);
        } else if (type == 3) {
            try {
                Integer.valueOf(exceptedResult);
            } catch (NumberFormatException e) {
                throw new ValidException("响应状态码预期结果错误");
            }
        }
    }
}




